package com.generator;

import com.redpig.generator.util.JDBCUtils;
import com.redpig.generator.vo.ClassVO;
import com.redpig.generator.vo.FieldVO;
import com.redpig.util.DateUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * Velocity生成静态页面
 * @author zqd
 */
public class GeneratorCodeForPureAdminServer {
    //模板使用的编码
    private static final String DEF_ENCODING = "UTF-8";

    //代码的包package
    private static String basePackageName = "com.redpig";

    //生成的代码存放目录:resources下
    private static String filePlace = "tmp/";

    //生成的文件存放目录
    private static String basePackageFolder = filePlace + basePackageName.replace(".","/");

    //vm模板存放目录
    private static String vmPlace = "generator/";

    //类名
    private static String className = "TableProperty";
    //表名
    private static String tableName = "redpig_sys_table_property";

    //类信息
    private static ClassVO classVO = new ClassVO();

    static{
        classVO.setBasePackageName(basePackageName);
        classVO.setClassName(className);
        classVO.setEntityName(classVO.getClassName().substring(0,1).toLowerCase()+classVO.getClassName().substring(1));
        classVO.setTableName(tableName);
        classVO.setDate(DateUtils.format(new Date()));
        classVO.setAuthor("zqd");
        classVO.setVersion("v1.0");
        classVO.setCopyright("Copyright: Copyright (c) 2023");
        classVO.setWebSite("www.redpig.vip");
    }

    /**
     * ☆☆☆☆☆☆☆☆☆☆
     * ☆☆☆☆☆☆☆☆☆☆
     * ☆☆☆☆☆☆☆☆☆☆
     * ☆☆☆☆☆☆☆☆☆☆
     *
     * 为了较少失误率，数据库generator、root、root
     *
     * @param args
     * @throws Exception
     */
    public static void main(String []args) throws Exception {

        /**
         * 根据表反射数据库字段
         */
        generatorVM(basePackageFolder+"/entity",  "server/Entity.vm",classVO.getClassName()+".java");
        generatorVM(basePackageFolder+"/mapper",  "server/Mapper.vm",classVO.getClassName()+"Mapper.java");
        generatorVM(basePackageFolder+"/service",  "server/IService.vm","I"+classVO.getClassName()+"Service.java");
        generatorVM(basePackageFolder+"/service/impl",  "server/ServiceImpl.vm",classVO.getClassName()+"ServiceImpl.java");
        generatorVM(basePackageFolder+"/controller",  "server/Controller.vm",classVO.getClassName()+"Controller.java");

        basePackageFolder = filePlace;
        generatorVM(basePackageFolder+"views/"+classVO.getEntityName(),"client/add.vm","add.vue");
        generatorVM(basePackageFolder+"views/"+classVO.getEntityName()+"/utils","client/hook.vm","hook.tsx");
        generatorVM(basePackageFolder+"views/"+classVO.getEntityName(),"client/list.vm","list.vue");
        generatorVM(basePackageFolder+"views/"+classVO.getEntityName()+"/utils","client/rule.vm","rule.ts");
        generatorVM(basePackageFolder+"views/"+classVO.getEntityName()+"/utils","client/types.vm","types.ts");


        generatorVM(basePackageFolder+"sql","sql/SQL.vm",classVO.getClassName()+".sql");

    }

    /**
     * @param folder 生成的文件存放位置(包目录名)【tmp下面的目录】
     * @param vm 模板位置+模板名称【不需要前缀generator】
     * @param fileName 生成的文件名
     * @throws Exception
     */
    private static void generatorVM(String folder,String vm,String fileName) throws Exception {
        GeneratorCodeForPureAdminServer generHtmlForVelocity = new GeneratorCodeForPureAdminServer();

        //生成的文件存放位置:tmp/com/redpig
        classVO.setPackageFolder(folder);

        generHtmlForVelocity.doRelease(vm,fileName);
    }

    /**
     *
     * @param vm 模板名
     * @param fileName 生成的文件名
     */
    public void doRelease(String vm,String fileName){
        try {
            Properties p = new Properties();
            p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
            p.setProperty(Velocity.ENCODING_DEFAULT, DEF_ENCODING);
            p.setProperty(Velocity.INPUT_ENCODING, DEF_ENCODING);

            Velocity.init(p);

            //模板位置
            Template template = getVelocityTemplate("src/main/resources/"+vmPlace+vm);
            VelocityContext context = initVelocityContext();
            BufferedWriter writer = getWriter(fileName);

            template.merge(context, writer);
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化VelocityContext
     * @author zqd
     */
    public VelocityContext initVelocityContext() throws Exception{
        VelocityContext context = new VelocityContext();
        try{
            List<FieldVO> fields = JDBCUtils.getTableFields(tableName);
            JDBCUtils.setClassVO(classVO);

            context.put("fields", fields);
            context.put("classVO", classVO);
        }catch(Exception e){
            e.printStackTrace();
        }
        return context;
    }

    /**
     * 获取Velocity模板
     * @author zqd
     * @param  velocityTemplateSource
     */
    public Template getVelocityTemplate(String velocityTemplateSource) throws Exception{
        Template template = new Template();
        try{
            template = Velocity.getTemplate(velocityTemplateSource);
        }catch(Exception e){
            e.printStackTrace();
        }
        return template;
    }

    /**
     * 获取Velocity写入流
     * @author zqd
     * @param  writerStreamSource
     */
    public BufferedWriter getWriter(String fileName) throws Exception{
        try{
            String packageFolder = "src/main/resources/"+classVO.getPackageFolder();
            File f = new File(packageFolder);
            f.mkdirs();

            FileOutputStream fos = new FileOutputStream(packageFolder+"/"+fileName);
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, DEF_ENCODING));
            return writer;
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }

}
